package com.coalmine.api.controller;


import cn.hutool.core.util.StrUtil;
import com.coalmine.api.annotation.LoginRequired;
import com.coalmine.api.domain.ApiApprove;
import com.coalmine.api.domain.ApiConfig;
import com.coalmine.api.domain.ApiGroup;
import com.coalmine.api.domain.ApiStat;
import com.coalmine.api.domain.req.ListResourceByTypeReqVO;
import com.coalmine.api.domain.resp.ListResourceByTypeRespVO;
import com.coalmine.api.enums.EApproveStatus;
import com.coalmine.api.service.*;
import com.coalmine.api.util.Constants;
import com.coalmine.common.constant.HttpStatus;
import com.coalmine.common.core.controller.BaseController;
import com.coalmine.common.core.domain.AjaxResult;
import com.coalmine.common.core.page.TableDataInfo;
import com.coalmine.common.core.redis.RedisCache;
import com.coalmine.common.utils.CollectionUtils;
import com.coalmine.common.utils.DateUtils;
import com.coalmine.common.utils.SecurityUtils;
import com.coalmine.common.utils.StringUtils;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiOperation;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.*;

import javax.servlet.http.HttpServletRequest;
import javax.validation.Valid;
import java.util.*;
import java.util.stream.Collectors;

/**
 * 接口申请
 *
 * @author zjx
 * @since 2022-07
 */
@Slf4j
@Api(tags = "API-接口申请")
@RestController
@RequestMapping("/api/apply")
public class ApiApplyController extends BaseController {

    @Autowired
    private IApiApplyService apiApplyService;

    @Autowired
    private IApiApproveService iApiApproveService;

    @Autowired
    private IApiTokenService tokenService;

    @Autowired
    private IApiConfigService apiConfigService;

    @Autowired
    private IApiGroupService apiGroupService;

    @Autowired
    private IApiStatService apiStatService;

    @Autowired
    private RedisCache redisCache;

    @Autowired
    private HttpServletRequest request;

    @Deprecated // 请使用/api/resource/apply
    @PostMapping("/add")
    @ApiOperation("新增申请")
    AjaxResult add(@Valid @RequestBody ApiApprove apiApprove) {
        //添加用户id
        apiApprove.setApplyUserId(SecurityUtils.getLoginUser().getUserId());
        //添加用户名秤
        //apiApprove.setApplyUserName(SecurityUtils.getLoginUser().getUsername());
        //获取审批状态，返回提示：0 申请中 ，1已申请通过， 2申请未通过
        List<ApiApprove> list = iApiApproveService.selectListByWrapper(apiApprove);
        if(list.size() == 0){
            //未申请过，新增申请
            return toAjax(apiApplyService.add(apiApprove));
        }
        int type = list.get(0).getApproveType();
        if(type == EApproveStatus.PENDING.getCode()) {
            return AjaxResult.error("审批中，请勿重复申请");
        }else if(type == EApproveStatus.APPROVED.getCode() ) {
            //获取到tokeng过期时间
            boolean b = tokenService.checkTokenExpire(list.get(0).getTokenId());
            if(b){
                //过期了，新增申请
                return toAjax(apiApplyService.add(apiApprove));
            }
            //未过期
            return AjaxResult.error("已通过且token未过期，请勿重复申请");
        } else {
            //申请失败，再申请
            return toAjax(apiApplyService.add(apiApprove));
        }
    }

    @PostMapping("/getType")
    @ApiOperation("获取申请状态")
    AjaxResult getApproveType(@RequestBody ApiApprove apiApprove) {
        if (StrUtil.isBlank(apiApprove.getApiId()) || StrUtil.isBlank(apiApprove.getGroupId()) ) {
            return AjaxResult.error(HttpStatus.BAD_REQUEST, "参数错误！");
        }
        //添加用户id
        apiApprove.setApplyUserId(SecurityUtils.getLoginUser().getUserId());
        ////获取审批状态，返回提示：0 申请中 ，1 已申请通过， 2 申请未通过
        List<ApiApprove> list = iApiApproveService.selectListByWrapper(apiApprove);
        HashMap<String,Object> map = new  HashMap<>();
        if(list != null && list.size() != 0 ){
            //0.1.2三种状态
            map.put("approveType",list.get(0).getApproveType());
            map.put("token","");
            map.put("applyName",list.get(0).getApplyName());
            map.put("approveReason",list.get(0).getApproveReason());
            map.put("applyReason",list.get(0).getApplyReason());
            if(list.get(0).getApproveType() == EApproveStatus.APPROVED.getCode()){
                //审批状态1,返回token
                String s = list.get(0).getTokenId();
                System.out.println(s);
                String token = tokenService.getTokenById(list.get(0).getTokenId()).getToken();
                if(StrUtil.isNotBlank(token)){
                    map.put("token",token);
                }
            }
        } else{//从没有申请记录
            map.put("approveType",-1);
            map.put("token","");
            map.put("applyName","");
            map.put("approveReason","");
            map.put("applyReason","");
        }
        return AjaxResult.success(map);
    }

    @PostMapping("/listByType")
    @ApiOperation("查询申请列表")
    @LoginRequired(required = true)
    TableDataInfo listByType(@RequestBody ListResourceByTypeReqVO reqVO) {
        TableDataInfo resp = new TableDataInfo();
        Integer pageNum = reqVO.getPageNum() != null ? reqVO.getPageNum() : 1;
        Integer pageSize = reqVO.getPageSize() != null ? reqVO.getPageSize() : 10;
        String tokenId = request.getHeader("id");
        List<ApiApprove> approveList = apiApplyService.listByToken(tokenId, reqVO.getType());
        if (approveList.size() == 0) {
            resp.setCode(HttpStatus.SUCCESS);
            resp.setMsg("暂无数据！");
            return resp;
        }
        List<String> apiIds = approveList.stream().map(ApiApprove::getApiId).collect(Collectors.toList());
        List<ApiApprove> authedApproveList = apiApplyService.listByTokenApi(tokenId, Constants.AUTH_TOKEN_GROUP_API_FLAG);
        if (authedApproveList.size() > 0) {
            Set<String> authedGroupIds = authedApproveList
                    .stream()
                    .map(ApiApprove::getGroupId)
                    .collect(Collectors.toSet());
            List<ApiConfig> authedApiList = apiConfigService.listByGroupIds(new ArrayList<>(authedGroupIds));
            Set<String> authedApiIds = authedApiList.stream()
                    .map(ApiConfig::getId)
                    .collect(Collectors.toSet());
            approveList.addAll(authedApproveList);
            apiIds.addAll(authedApiIds);
        }

        List<ApiConfig> apiConfigList = apiConfigService.listByIds(apiIds);
        // <apiId, apiName>
        Map<String, String> apiNameMap;
        if (StringUtils.isEmpty(reqVO.getResourceName())) {
            apiNameMap = apiConfigList.stream()
                    .collect(Collectors.toMap(ApiConfig::getId, ApiConfig::getName));
        } else {
            apiNameMap = apiConfigList.stream()
                    .filter(a -> a.getName().contains(reqVO.getResourceName()))
                    .collect(Collectors.toMap(ApiConfig::getId, ApiConfig::getName));
        }
        // <apiId, groupName>
        List<String> groupIds = approveList.stream().map(ApiApprove::getGroupId).collect(Collectors.toList());
        List<ApiGroup> groupList = apiGroupService.listByIds(groupIds);
        Map<String, String> apiGroupNameMap;
        if (StringUtils.isNull(reqVO.getGroupId())) {
            apiGroupNameMap = groupList.stream()
                    .collect(Collectors.toMap(ApiGroup::getId, ApiGroup::getName));
        } else {
            apiGroupNameMap = groupList.stream()
                    .filter(g -> g.getId().equals(reqVO.getGroupId()))
                    .collect(Collectors.toMap(ApiGroup::getId, ApiGroup::getName));
        }

        List<ListResourceByTypeRespVO> data = new ArrayList<>();
        // 全部列表 || 已通过列表
        if (StringUtils.isEmpty(reqVO.getType())
                || EApproveStatus.APPROVED.getCode() == Integer.parseInt(reqVO.getType())) {
            approveList.stream().forEach(a -> {
                if ((!apiNameMap.containsKey(a.getApiId()))
                        || (!apiGroupNameMap.containsKey(a.getGroupId()))) {
                    return;
                }
                ListResourceByTypeRespVO respVO = new ListResourceByTypeRespVO();
                BeanUtils.copyProperties(a, respVO);
                respVO.setStatus(String.valueOf(a.getApproveType()));
                respVO.setApiName(apiNameMap.get(a.getApiId()));
                respVO.setGroupName(apiGroupNameMap.get(a.getGroupId()));
                respVO.setApplyTime(DateUtils.parseDateToStr(DateUtils.YYYY_MM_DD_HH_MM_SS, a.getApplyTime()));
                ApiStat stat = apiStatService.statByApiUser(a.getApiId());
                if (stat != null) {
                    respVO.setSuccessTimes(stat.getSuccessTimes());
                    respVO.setFailureTimes(stat.getFailureTimes());
                }
                data.add(respVO);
            });
            List<ListResourceByTypeRespVO> dataRespVO = CollectionUtils.managerPage(data, pageNum, pageSize);
            resp.setCode(HttpStatus.SUCCESS);
            resp.setMsg("查询成功");
            resp.setRows(dataRespVO);
            resp.setTotal(data.size());
            return resp;
        }
        // 审批中列表 || 未通过列表
        if (EApproveStatus.PENDING.getCode() == Integer.parseInt(reqVO.getType())
                || EApproveStatus.REJECTED.getCode() == Integer.parseInt(reqVO.getType())) {
            approveList.stream().forEach(a -> {
                if ((!apiNameMap.containsKey(a.getApiId()))
                        || (!apiGroupNameMap.containsKey(a.getGroupId()))) {
                    return;
                }
                ListResourceByTypeRespVO respVO = new ListResourceByTypeRespVO();
                BeanUtils.copyProperties(a, respVO);
                respVO.setStatus(String.valueOf(a.getApproveType()));
                respVO.setApplyTime(DateUtils.parseDateToStr(DateUtils.YYYY_MM_DD_HH_MM_SS, a.getApplyTime()));
                respVO.setApiName(apiNameMap.get(a.getApiId()));
                respVO.setGroupName(apiGroupNameMap.get(a.getGroupId()));
                data.add(respVO);
            });
            List<ListResourceByTypeRespVO> dataRespVO = CollectionUtils.managerPage(data, pageNum, pageSize);
            resp.setCode(HttpStatus.SUCCESS);
            resp.setMsg("查询成功");
            resp.setRows(dataRespVO);
            resp.setTotal(data.size());
            return resp;
        }
        // 错误的审批状态
        else {
            resp.setCode(HttpStatus.ERROR);
            resp.setMsg("未知的审批状态！");
            return resp;
        }
    }

    @ApiOperation("api分组下拉框")
    @GetMapping("/getAllGroup")
    @LoginRequired(required = true)
    public AjaxResult getAllGroup() {
        List<ApiGroup> all = apiGroupService.getAll();
        return AjaxResult.success(all);
    }
}
